package student;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.ResultSet;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;

@WebServlet("/StudentGradeServlet")
public class StudentGradeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String keyword = request.getParameter("keyword");
        HttpSession session = request.getSession(false);
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter out = response.getWriter();
        Map<String, Object> jsonResponse = new HashMap<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");

        if (session == null || session.getAttribute("student_id") == null) {
            jsonResponse.put("success", false);
            jsonResponse.put("code", 401);
            jsonResponse.put("message", "会话已过期，请重新登录");
            out.print(mapToJson(jsonResponse));
            return;
        }

        Integer studentId = (Integer) session.getAttribute("student_id");

        try {
            Connectmysql conn = new Connectmysql(
                    "jdbc:mysql://localhost:3306/exam",
                    "root", "root", "com.mysql.cj.jdbc.Driver");

            if (conn.open()) {
                // 成绩概览数据
                String overviewSql = "SELECT " +
                        "SUM(is_passed) AS passed_count, " +
                        "SUM(NOT is_passed) AS failed_count, " +
                        "AVG(score) AS average_score " +
                        "FROM student_score WHERE student_id = ?";

                ResultSet rs = conn.executeSql(overviewSql, new Object[]{studentId});
                if (rs.next()) {
                    jsonResponse.put("passedCount", rs.getInt("passed_count"));
                    jsonResponse.put("failedCount", rs.getInt("failed_count"));

                    // 格式化平均分
                    double avgScore = rs.getDouble("average_score");
                    jsonResponse.put("averageScore", Math.round(avgScore * 100) / 100.0);
                }

                // 成绩列表
                String gradeSql = "SELECT s.score, s.is_passed, e.exam_name, c.course_name, e.start_time " +
                        "FROM student_score s " +
                        "JOIN exam e ON s.exam_id = e.exam_id " +
                        "JOIN course c ON e.course_id = c.course_id " +
                        "WHERE s.student_id = ? " +
                        (keyword != null && !keyword.isEmpty() ?
                                "AND (c.course_name LIKE ? OR e.exam_name LIKE ?) " : "") +
                        "ORDER BY e.start_time DESC";

                Object[] params;
                if (keyword != null && !keyword.isEmpty()) {
                    params = new Object[]{studentId, "%" + keyword + "%", "%" + keyword + "%"};
                } else {
                    params = new Object[]{studentId};
                }

                rs = conn.executeSql(gradeSql, params);
                List<Map<String, Object>> grades = new ArrayList<>();

                while (rs.next()) {
                    Map<String, Object> grade = new LinkedHashMap<>();
                    grade.put("score", rs.getDouble("score"));
                    grade.put("is_passed", rs.getBoolean("is_passed"));
                    grade.put("exam_name", escapeJson(rs.getString("exam_name")));
                    grade.put("course_name", escapeJson(rs.getString("course_name")));

                    // 格式化时间
                    Timestamp startTime = rs.getTimestamp("start_time");
                    grade.put("start_time", startTime != null ?
                            escapeJson(sdf.format(startTime)) : "N/A");

                    grades.add(grade);
                }

                jsonResponse.put("grades", grades);
                jsonResponse.put("success", true);
            }
        } catch (Exception e) {
            e.printStackTrace();
            jsonResponse.put("success", false);
            jsonResponse.put("message", "加载成绩失败: " + e.getMessage());
        } finally {
            out.print(mapToJson(jsonResponse));
            out.flush();
        }
    }

    private String mapToJson(Map<String, Object> map) {
        StringBuilder json = new StringBuilder("{");
        boolean first = true;

        for (Map.Entry<String, Object> entry : map.entrySet()) {
            if (!first) {
                json.append(",");
            }
            first = false;

            json.append("\"").append(escapeJson(entry.getKey())).append("\":");

            Object value = entry.getValue();
            if (value == null) {
                json.append("null");
            } else if (value instanceof String) {
                json.append("\"").append(escapeJson((String) value)).append("\"");
            } else if (value instanceof Boolean) {
                json.append(value);
            } else if (value instanceof Number) {
                json.append(value);
            } else if (value instanceof List) {
                json.append(listToJson((List<?>) value));
            } else {
                json.append("\"").append(escapeJson(value.toString())).append("\"");
            }
        }

        json.append("}");
        return json.toString();
    }

    private String listToJson(List<?> list) {
        StringBuilder json = new StringBuilder("[");
        boolean first = true;

        for (Object item : list) {
            if (!first) {
                json.append(",");
            }
            first = false;

            if (item instanceof Map) {
                json.append(mapToJson((Map<String, Object>) item));
            } else if (item instanceof String) {
                json.append("\"").append(escapeJson((String) item)).append("\"");
            } else if (item instanceof Boolean) {
                json.append(item);
            } else if (item instanceof Number) {
                json.append(item);
            } else {
                json.append("\"").append(escapeJson(item.toString())).append("\"");
            }
        }

        json.append("]");
        return json.toString();
    }

    private String escapeJson(String input) {
        if (input == null) return "";
        return input.replace("\\", "\\\\")
                .replace("\"", "\\\"")
                .replace("\b", "\\b")
                .replace("\f", "\\f")
                .replace("\n", "\\n")
                .replace("\r", "\\r")
                .replace("\t", "\\t");
    }
}